#ifndef __WEBPAGEQUERY_H__
#define __WEBPAGEQUERY_H__

#include <sw/redis++/redis++.h>
#include "cppjieba/Jieba.hpp"
#include <unordered_map>
#include <vector>
#include <set>
#include <string>
#include <iostream>
#include <hiredis/hiredis.h>
#include <unordered_set>
#include <tuple>
#include <cmath>
#include <fstream>
#include <sstream>
#include <nlohmann/json.hpp>
#include <locale>
#include <set>
#include <map>
#include <codecvt>
#include <chrono>
// #include "fifo_map.hpp"
using std::pair;
using std::tuple;
using std::unordered_map;
using std::unordered_set;
using std::vector;
using std::wstring;
using json = nlohmann::json;
using std::string;
using WordSegmentation = cppjieba::Jieba;
using std::cout;
using std::endl;
using std::set;
using std::map;
using std::ifstream;
// template<class K, class V, class dummy_compare, class A>
// using my_workaround_fifo_map = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare<K>, A>;
// using my_json = nlohmann::basic_json<my_workaround_fifo_map>;

class WebPageQuery
{
public:
    string doQuery(const string &str);
    void loadLibrary();
    vector<double> getQueryWordsWeightVector(vector<string> &queryWords);
    string createJson(vector<int> &docIdVec, const vector<string> &queryWords);
    string returnNoAnswer();
    WebPageQuery(const string &invertindex, const string &cnDic,
                 const string &enDic, const string &cnStopFile,
                 const string &enStopFile, const string &pageLibFile)
        : _jieba("../include/cppjieba/dict/jieba.dict.utf8",
                 "../include/cppjieba/dict/hmm_model.utf8",
                 "../include/cppjieba/dict/user.dict.utf8",
                 "../include/cppjieba/dict/idf.utf8",
                 "../include/cppjieba/dict/stop_words.utf8"),
          _redis("tcp://127.0.0.1:6379")
    {
        cout << "Redis 连接成功 tcp://127.0.0.1:6379" << endl;
        loadInv(invertindex);
        cout << "加载倒排索引库成功" << endl;
        loadStop(cnStopFile);
        cout << "加载中文停用词成功" << endl;
        loadStop(enStopFile);
        cout << "加载英文停用词成功" << endl;
        loadPageLib(pageLibFile);
        cout << "加载网页库成功" << endl;
    }
    ~WebPageQuery()
    {
    }

public:
#if 0
    static WebPageQuery *getInstance(const string &invertindex, const string &cnDic,
                                     const string &enDic, const string &cnStopFile,
                                     const string &enStopFile, const string &pageLibFile)
    {
        if (_pInstance == nullptr)
        {
            _pInstance = new WebPageQuery(invertindex, cnDic, enDic, cnStopFile,
                                          enStopFile, pageLibFile);
        }
        return _pInstance;
    }
#endif
private:
    void loadInv(const string &filename);
    void loadStop(const string &filename);
    void loadPageLib(const string &filename);
    bool isStoreInv(vector<string> words);
    void calcuCos(const vector<double> &x);
    void obtainSummary();
    string createJson();

private:
    WordSegmentation _jieba;
    unordered_map<int, vector<string>> _pageLib; // 网页库，放入redis
    unordered_map<string, set<pair<int, double>>> _invertIndexTable;
    unordered_map<string, int> _df;
    // unordered_map<string, int> _tf;
    unordered_set<string> _stop;
    vector<string> _searchKeys;
    unordered_map<int, int> _unionId;
    vector<pair<int, int>> _textIdOrder;
    unordered_map<int, string> _textSummary;
    vector<tuple<int, int, double>> _textOrder; // 最终找到的文章id，依次按文章中出现的关键字数，余弦相似度排序
    int _maxId = 0;
    sw::redis::Redis _redis;
    //static WebPageQuery *_pInstance;
    // MyRedis myRedis;
    //  redisContext *_redisHindle;
};

#endif